#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(horChange(int)));
    connect(ui->verticalSlider, SIGNAL(valueChanged(int)), this, SLOT(verChange(int)));

    m_img = QImage("F:1.jpg");
    m_img_dst = m_img;
    updateQLabelImage();
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 更新QLabel里面的图像
void MainWindow::updateQLabelImage()
{
    // m_img = m_img.scaled(ui->label->width(), ui->label->height());
    QImage img_show = m_img_dst.scaled(ui->label->width(), ui->label->height());
    ui->label->setPixmap(QPixmap::fromImage(img_show));
}

Mat MainWindow::QImage2Mat(QImage &img)
{
    cv::Mat mat;
    switch (img.format())
    {
    case QImage::Format_RGB32:  //一般Qt读入彩色图后为此格式
        mat = cv::Mat(img.height(), img.width(), CV_8UC4, (void*)img.constBits(), img.bytesPerLine());
        cv::cvtColor(mat,mat,cv::COLOR_BGRA2BGR);   //转3通道
        break;
    case QImage::Format_RGB888:
        mat = cv::Mat(img.height(), img.width(), CV_8UC3, (void*)img.constBits(), img.bytesPerLine());
        cv::cvtColor(mat,mat,cv::COLOR_RGB2BGR);
        break;
    case QImage::Format_Indexed8:
        mat = cv::Mat(img.height(), img.width(), CV_8UC1, (void*)img.constBits(), img.bytesPerLine());
        break;
    }
    return mat;
}

QImage MainWindow::Mat2QImage(Mat &img)
{
    if(img.type()==CV_8UC1 || img.type()==CV_8U)
    {
        QImage image((const uchar *)img.data, img.cols, img.rows, img.step, QImage::Format_Grayscale8);
        return image;
    }
    else if(img.type()==CV_8UC3)
    {
        QImage image((const uchar *)img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
        return image.rgbSwapped();  //r与b调换
    }
}

int MainWindow::hDLL_gradientAuto(Mat &src, Mat &dst, int flag, int val)
{
    if(flag != 0 && flag != 1 && flag != 2 && flag != 3) return -1;
    if(val < 10 || val > 100) return -1;

    int width = src.cols;
    int height = src.rows;
    Mat M;
    // flag 方向,[0(左),1(上),2(右),3(下)]
    switch (flag) {
    case 0:
    {
        Point2f pts_src[] = { Point(val,val), Point(width, 0), Point(width, height), Point(val, height-val)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 1:
    {
        Point2f pts_src[] = { Point(val,val), Point(width-val, val), Point(width, height), Point(0, height)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 2:
    {
        Point2f pts_src[] = { Point(0,0), Point(width-val, val), Point(width-val, height-val), Point(0, height)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    case 3:
    {
        Point2f pts_src[] = { Point(0,0), Point(width, 0), Point(width-val, height-val), Point(val, height-val)};
        Point2f pts_dst[] = { Point(0, 0), Point(width, 0), Point(width, height) ,Point(0, height) };
        M = cv::getPerspectiveTransform(pts_src, pts_dst);
    }break;
    }

    cv::warpPerspective(src, dst, M, dst.size(), cv::INTER_LINEAR , cv::BORDER_REPLICATE);
    return 0;
}

// 横向改变
void MainWindow::horChange(int index)
{
    qDebug() << "hor:" << index;

    if(index == 0)
    {
        m_img_dst = m_img;
    }
    else if(index < 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 0, val);
        m_img_dst = Mat2QImage(dst);
    }
    else if (index > 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 2, val);
        m_img_dst = Mat2QImage(dst);
    }
    updateQLabelImage();
}

// 竖向改变
void MainWindow::verChange(int index)
{
    qDebug() << "ver:" << index;

    if(index == 0)
    {
        m_img_dst = m_img;
    }
    else if(index < 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 3, val);
        m_img_dst = Mat2QImage(dst);
    }
    else if (index > 0)
    {
        int val = abs(index) * 10;
        Mat src = QImage2Mat(m_img);
        Mat dst;
        hDLL_gradientAuto(src, dst, 1, val);
        m_img_dst = Mat2QImage(dst);
    }

    updateQLabelImage();
}
